// 多线程并发服务器模型
#include <stdio.h>
#include <stdlib.h>
#include <sys/unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <netinet/ip.h>
#include <pthread.h>
#include <string.h>
#define PORT 8888
#define BACKLOG 20
#define BUFFSIZE 4096
struct ClientInfo
{
    int clientFd;
};
pthread_mutex_t mutex;
void* dealClientConnection(void* arg);
int main(void)
{
    pthread_mutex_init(&mutex, NULL);
    printf("hello world.\n");
    int serverFd;
    serverFd = socket(AF_INET, SOCK_STREAM, 0);
    if (serverFd > 0)
    {
        printf("socket create successed.\n");
    }
    else
    {
        printf("socket create failed.\n");
    }
    struct sockaddr_in serverInfo;
    memset(&serverInfo, 0, sizeof serverInfo);
    serverInfo.sin_family = AF_INET;
    serverInfo.sin_port = htons(PORT);
    inet_aton("127.0.0.1", &serverInfo.sin_addr);
    int err = bind(serverFd, (struct sockaddr*)&serverInfo, sizeof serverInfo);
    if (err == 0)
    {
        printf("bind successed.\n");
    }
    else
    {
        printf("bind failed.\n");
    }
    err = listen(serverFd, BACKLOG);
    if (err == 0)
    {
        printf("listen successed.\n");
    }
    else
    {
        printf("listen failed.\n");
    }
    struct sockaddr_in clientInfo;
    memset(&clientInfo, 0, sizeof clientInfo);
    socklen_t clientInfoLen = sizeof clientInfo;
    while (1)
    {
        pthread_mutex_lock(&mutex);
        int clientFd = accept(serverFd, (struct sockaddr*)&clientInfo, &clientInfoLen);
        if (clientFd > 0)
        {
            printf("accept successed.\n");
            pthread_t pid;
            struct ClientInfo myArg;
            myArg.clientFd = clientFd;
            pthread_create(&pid, NULL, dealClientConnection, (void*)&myArg);
            pthread_detach(pid);
        }
        else
        {
            printf("accept failed.\n");
        }
    }


    return 0;
}
void* dealClientConnection(void* arg)
{
    struct ClientInfo curClient = *(struct ClientInfo*)arg;
    pthread_mutex_unlock(&mutex);
    int clientFd = curClient.clientFd;
    printf("start deal clientFd: %d\n", clientFd);
    char buffer[BUFFSIZE] = {0};
    while (1)
    {
        int n = read(clientFd, buffer, sizeof buffer);
        if (n <= 0)
        {
            close(clientFd);
            printf("clientFd:%d over.\n", clientFd);
            return NULL;
        }
    }

    return NULL;
}